<?php
/**
 * Created by PhpStorm.
 * User: yiyu
 * Email: smalleasyu@gmail.com
 * Date: 2020-01-31 13:13:40
 * Desc:
 */

namespace app\base\service\Pay;

use app\base\service\BaseService;
use app\base\model\order\{Order, OrderGroup};
use app\base\model\user\{User, UserAccountLog, UserWx, UserFriend, UserAccount, UserStatisticsInfo};
use app\base\model\goods\{GoodsBaseInfo, GoodsGroupInfo, GoodsGroupJoinInfo, GoodsStatisticsInfo};
use app\base\model\address\UserPostInfo;
use app\api\service\GoodsService;
use app\core\exception\{BusinessException, ErrorCode};
use app\core\log\Log4dd;
use think\Db;
use think\Request;

class OrderService extends BaseService
{

    /**
     * Desc: 创建系统订单
     * Date: 2020/2/18 23:36
     * Author: yiyu
     * @param $user_id
     * @param $group_goods_ids
     * @param array $base_info
     * @return array
     */
    public static function createSystemNewOrder($user_id, $group_goods_ids, $base_info = [])
    {

        Log4dd::info('创建新订单,记录请求参数', func_get_args());

        $param_info['pay_way'] = $base_info['pay_way'];

        $param_info['pay_mode'] = $base_info['pay_mode'];

        if (!isset($base_info['order_money']) || empty($base_info['order_money']) || $base_info['order_money'] <= 0) {
            throw new BusinessException(ErrorCode::COMMON_ERROR, '应付金额order_money有误');
        }

        $param_info['order_money'] = $base_info['order_money'];

        $param_info['pay_money'] = $base_info['pay_money'] ?? $base_info['order_money'];

        if (!isset($base_info['original_money'])) {
            $param_info['original_money'] = $base_info['order_money'];
        }

        $param_info['is_robot'] = $base_info['is_robot'] ? 1 : 0;
        $param_info['order_remark'] = $base_info['order_remark'] ?? '';


        $open_id = '';
        //小程序支付需要open_id
        if ($param_info['pay_mode'] == Order::PAY_WAY_WX_MINI && $param_info['is_robot'] == 0) {
            if (!isset($base_info['app_id']) || empty($base_info['app_id'])) {
                Log4dd::error('小程序支付创建新订单,app_id为空', $base_info);
                throw new BusinessException(ErrorCode::COMMON_ERROR, '缺少必要的参数');
            }
            $open_id = UserWx::getOpenIdByUserId($user_id, $base_info['app_id'], UserWx::MINI_PROGRAM_OPEN_ID_TYPE);
            if (empty($open_id)) {
                throw new BusinessException(ErrorCode::COMMON_ERROR, '未获取到open_id');
            }
        }

        Log4dd::info('创建新订单,记录param_info', $param_info);

        Db::startTrans();

        try {

            $curr_time = time();

            $create_ip = Request::instance()->ip();

            $order_info = [
                'user_id' => $user_id,
                'order_no' => self::createOderNo(),
                'order_state' => $param_info['is_robot'] == 1 ? Order::ORDER_SUCCESS : Order::ORDER_NOT_PAY,
                'show_user_order' => self::createShowUserOrderNo(),
                'wx_pay_end_time' => self::getWxPayEndTime(),
                'create_time' => date('Y-m-d H:i:s', $curr_time),
                'create_ip' => $create_ip
            ];


            $new_order_info = array_merge($order_info, $param_info);

            Log4dd::info('创建新订单,记录new_order_info', $new_order_info);

            $orderInfo = Order::create($new_order_info);

            if (!$orderInfo['order_id']) {
                Db::rollback();
            }

            $order_group_data = [];

            foreach ($group_goods_ids as $item) {
                $order_group_data[] = [
                    'order_id' => $orderInfo['order_id'],
                    'support_user_id' => $user_id,
                    'initiate_user_id' => $item['user_id'] ?? 0,
                    'group_id' => $item['group_id'] ?? 0,
                    'goods_id' => $item['goods_id'] ?? 0,
                    'pay_money' => $item['pay_money'] ?? 0,
                    'get_gold_num' => $item['get_gold_num'] ?? 0,
                    'is_free_support' => $item['free_support'] ?? 0,
                    'create_time' => date('Y-m-d H:i:s', $curr_time),
                ];
            }

            Log4dd::info('创建新订单,记录order_group_data', $order_group_data);

            $orderGroup = new OrderGroup();

            $orderGroup->saveAll($order_group_data);

            Db::commit();

            $res = [
                'body' => '支持他人心愿',
                'out_trade_no' => $order_info['order_no'],
                'total_fee' => $param_info['pay_money'],
                'spbill_create_ip' => $create_ip,
                'open_id' => $open_id,
                'timestamp' => $curr_time
            ];

            Log4dd::info('创建新订单,最终返回数据', $res);

            return $res;

        } catch (BusinessException $e) {
            Db::rollback();
            Log4dd::error("创建新订单失败:{$e->getMessage()}", func_get_args(), $e);
            throw new BusinessException(ErrorCode::COMMON_ERROR, '下单失败');
        }
    }

    public static function createOderNo()
    {
        return md5(uniqid(md5(microtime(true)), true));
    }

    public static function getWxPayEndTime($second = 7200)
    {
        $second <= 0 && $second = 7200;
        return date('Y-m-d H:i:s', time() + $second);
    }

    public static function createShowUserOrderNo()
    {
        return date('YmdHis') . rand(1000, 9999);
    }

    /**
     * Desc: 订单成功，处理拼团的相关信息
     * Date: 2020/2/18 23:36
     * Author: yiyu
     * @param $user_id
     * @param $order_id
     * @param $order_no
     * @param $is_free_support
     * @return bool
     */
    public static function orderSuccess($user_id, $order_id, $order_no, $is_free_support = false)
    {

        try {

            Db::startTrans();

            if ($order_id) {
                $order_info = Order::where('order_id', $order_id)->find();
            } elseif ($order_no) {
                $order_info = Order::where('order_no', $order_no)->find();
            }

            if (empty($order_info)) {
                throw new BusinessException(ErrorCode::COMMON_ERROR, '订单不存在，不予处理');
            }

            //1 给支持者赠送应得的心愿币
            //根据订单id获取支持的相关信息
            $group_items = OrderGroup::where('order_id', $order_info['order_id'])->where('support_user_id', $user_id)->select();

            if (empty($group_items)) {
                throw new BusinessException(ErrorCode::COMMON_ERROR, '未查询到参与信息');
            }

            $user_account_type = User::getUserFieldById($user_id, 'account_type');

            $is_robot = $user_account_type == User::ACCOUNT_TYPE_ROBOT ? 1 : 0;

            $date = date('Y-m-d H:i:s');

            //机器人支持更新支付时间
            if ($is_robot) {
                Order::where('order_id', $order_info['order_id'])->update(['pay_finish_time' => $date]);
            }

            Log4dd::info('订单完成：赠送及更新相关数据', $group_items);

            //更新拼团进度，更新用户和商品统计
            $user_statistics_info = UserStatisticsInfo::find($user_id);

            $is_first_pay = (empty($user_statistics_info) || ($user_statistics_info && $user_statistics_info['pay_num'] <= 0)) ? true : false;

            $has_first_give = false;

            foreach ($group_items as $group_item) {
                //首次支付额外赠送心愿币
                if (false == $is_free_support && $is_first_pay && false == $has_first_give) {
                    $extra_give = GoodsService::getFirstSupportWishGiveWishCoinNum();
                    if ($extra_give) {
                        $first_operation_res = UserAccount::operationUserAccount($user_id,
                            $group_item['initiate_user_id'], UserAccount::WISH_COIN, $extra_give, UserAccount::FIRST_SUPPORT_OPERATION_TYPE,
                            '首次支持TA人心愿,系统赠送', $group_item['group_id']);
                        Log4dd::info('订单完成: 首次支付额外赠送心愿币',
                            [func_get_args(), $group_item, $is_first_pay, $extra_give, $first_operation_res]);
                        if (empty($first_operation_res) || !isset($first_operation_res['err_num']) || $first_operation_res['err_num'] != 0) {
                            Db::rollback();
                            throw new BusinessException(ErrorCode::COMMON_ERROR, '赠送心愿币失败');
                        }
                    }

                    $has_first_give = true;
                }

                $nick_name = User::getNickNameById($group_item['initiate_user_id']);

                $goods_name = GoodsBaseInfo::getGoodsBaseInfoByField($group_item['goods_id'], 'goods_name');

                //每单进行赠送心愿币
                $operation_type = $is_free_support ? 'free_support_wish' : 'support_wish';
                $description = $is_free_support ? '首次免费支持了' : '支持了';
                $operation_res = UserAccount::operationUserAccount($user_id, $group_item['initiate_user_id'],
                    UserAccount::WISH_COIN,
                    $group_item['get_gold_num'], $operation_type, $description. ' <span style="color: #333333;font-weight: bold;">' . $nick_name . '</span> 的 <span style="color: #333333;font-weight: bold;"> ' . $goods_name. ' </span> 心愿', $group_item['group_id']);
                Log4dd::info('订单完成：对每单进行赠送', [func_get_args(), $group_item, $operation_res]);
                if (empty($operation_res) || !isset($operation_res['err_num']) || $operation_res['err_num'] != 0) {
                    Db::rollback();
                    throw new BusinessException(ErrorCode::COMMON_ERROR, '赠送心愿币失败');
                }

                $group_join_info = [
                    'group_id' => $group_item['group_id'],
                    'user_id' => $user_id,
                    'is_robot' => $is_robot,
                    'order_id' => $order_info['order_id'],
                    'get_gold_num' => $group_item['get_gold_num'],
                    'is_free_support' => $is_free_support ? 1 : 0,
                    'create_time' => $date
                ];

                //更新拼团成员信息
                $join_info = GoodsGroupJoinInfo::create($group_join_info);

                if (empty($join_info) || !$join_info['join_id']) {
                    Db::rollback();
                    throw new BusinessException(ErrorCode::COMMON_ERROR, '更新拼团成员信息失败');
                }

                //互相绑定好友关系
                UserFriend::bindFriendByFriendUserId($user_id, $group_item['initiate_user_id'], UserFriend::SOURCE_MINI_SUPPORT_WISH);
                UserFriend::bindFriendByFriendUserId($group_item['initiate_user_id'], $user_id, UserFriend::SOURCE_MINI_BE_SUPPORT_WISH);

                //获取发起信息表信息
                $old_group_info = GoodsGroupInfo::find($group_item['group_id']);

                //更新发起原信息表
                $new_group_info['join_people'] = Db::raw('join_people+1');

                $need_people = $old_group_info['need_people'];

                //将拼团置为已完成
                $join_people = $old_group_info['join_people'] + 1;
                if ($need_people <= $join_people) {
                    $new_group_info['group_state'] = GoodsGroupInfo::GROUP_SUCCESS_STATE;
                    $new_group_info['success_time'] = date('Y-m-d H:i:s');
                    \app\base\service\WeChat\MiniProgramSubscribeMessageService::instance()->sendWishFinishNoticeMsg([
                        'group_id' => $group_item['group_id'],
                        'first' => $goods_name,
                        'keyword1' => config('wish_num_prefix') . $group_item['group_id'],
                        'keyword2' => date('Y年m月d日 H:i:s'),
                        'keyword3' => '你发起的好物心愿已达成！点击可查看详情',
                    ], $group_item['initiate_user_id']);
                } else {
                    //只有在第一次进度>=30被支持的时候才发消息，因为有可能是一次性订阅消息，不能使用别的机会
                    if ($join_people / $need_people >= 0.3 && ($old_group_info['join_people'] / $need_people < 0.3)) {
                        \app\base\service\WeChat\MiniProgramSubscribeMessageService::instance()->sendWishProgressNoticeMsg([
                            'group_id' => $group_item['group_id'],
                            'first' => $goods_name,
                            'keyword1' => config('wish_num_prefix') . $group_item['group_id'],
                            'keyword2' => '得到支持',
                            'keyword3' => date('Y年m月d日 H:i:s'),
                            'keyword4' => '你的好物心愿已得到' . $join_people. '人支持！点击查看详情'
                        ], $group_item['initiate_user_id']);
                    }
                }

                if ($is_robot) {
                    $new_group_info['robot_people'] = Db::raw('robot_people+1');
                    $new_group_info['is_auto_group'] = 1;
                }

                $new_group_info['group_curr_pay_price'] = Db::raw("group_curr_pay_price+{$group_item['pay_money']}");
                GoodsGroupInfo::where('group_id', $group_item['group_id'])->update($new_group_info);

                //成团了，则更新商品信息
                if (isset($new_group_info['group_state']) && $new_group_info['group_state'] == GoodsGroupInfo::GROUP_SUCCESS_STATE) {
                    GoodsStatisticsInfo::GoodsStatistics($group_item['goods_id'], 'success_num', 1);
                    //更新快递信息,改成已成团未发货
                    UserPostInfo::where('group_id', $group_item['group_id'])->where('user_id',
                        $group_item['initiate_user_id'])->update(['post_state' => 1]);
                }

                unset($new_group_info, $old_group_info, $need_people);

            }

            if (!$is_free_support) {
                //更新用户统计信息
                if ($is_first_pay) {
                    if (strtotime($user_statistics_info['first_pay_time']) <= 0) {
                        $statistics_data['first_pay_time'] = date('Y-m-d H:i:s');
                    }
                } else {
                    $statistics_data['first_pay_time'] = date('Y-m-d H:i:s');
                }

                $statistics_data['pay_num'] = Db::raw('pay_num+1');
                $statistics_data['pay_money_total'] = Db::raw("pay_money_total+{$order_info['pay_money']}");

                if (empty($user_statistics_info)) {
                    $statistics_data['user_id'] = $user_id;
                    UserStatisticsInfo::create($statistics_data);
                } else {
                    UserStatisticsInfo::where('user_id', $user_id)->update($statistics_data);
                }
            }

            //将订单置为成功
            if ($is_free_support) {
                $notify_data['order_state'] = Order::ORDER_SUCCESS;
                $notify_data['pay_finish_time'] = date('Y-m-d H:i:s');
                $notify_data['update_time'] = date('Y-m-d H:i:s');
                Order::where('order_no', $order_info['order_no'])->update($notify_data);// 保存订单
            }

            Db::commit();

            return true;

        } catch (BusinessException $e) {
            Db::rollback();
            Log4dd::error("订单完成：处理相关数据失败:{$e->getMessage()}", func_get_args(), $e);
            throw new BusinessException(ErrorCode::COMMON_ERROR, '处理失败');
        }

    }

}